package com.chinaunicom.sh.oss.antenna.code;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.thinkgem.jeesite.common.utils.StringUtils;

/**
 * 使用步骤:<br/>
 * 1：
 * 
 * @author liuchengbiao
 *
 */
public class GenerateCodeUtil {

	/** 记录导入的包 */
	private static List<String> importList = new ArrayList<String>();

	/** 排除默认字段，针对这些字段，将不解析成属性，因为已经继承了 */
	public static final List<String> EXCLUDE_FILED_LIST = new ArrayList<String>(
			Arrays.asList("id", "create_by", "create_date", "update_by", "update_date", "remarks", "del_flag"));

	/** 记录需要替换的包 */
	public static Map<String, String> importMap = new HashMap<String, String>();

	/** 表前缀，解析后默认将表前缀去掉 */
	public static final String TABLE_PREFFIX = "";

	static {
		// 如果此包需要替换，那么可以在此处修改基础包地址

		// importMap.put("IdEntity",
		// "com.chinaunicom.sh.oss.basic.common.persistence.IdEntity");
		// importMap.put("BaseDao",
		// "com.ustcinfo.ishare.eip.basic.common.persistence.BaseDao");
		// importMap.put("BaseController",
		// "com.ustcinfo.ishare.eip.basic.common.web.BaseController");

		importMap.put("IdEntity", "com.thinkgem.jeesite.common.persistence.IdEntity");
		importMap.put("BaseDao", "com.thinkgem.jeesite.common.persistence.BaseDao");
		importMap.put("BaseController", "com.thinkgem.jeesite.common.web.BaseController");
	}

	/**
	 * 自动生成代码<br/>
	 * 
	 * @param con
	 *            数据库连接对象
	 * @param tableNameList
	 *            表名称集合
	 */
	public static void code(Connection con, List<String> tableNameList, String packageName) {
		try {
			int count = 0;
			for (String tableName : tableNameList) {
				List<TableEntity> list = new ArrayList<TableEntity>();
				ResultSet rs = con.getMetaData().getColumns(null, null, tableName, null);
				while (rs.next()) {
					// 获得字段名称
					String columnName = rs.getString("COLUMN_NAME");
					if (GenerateCodeUtil.EXCLUDE_FILED_LIST.contains(columnName)) {
						continue;
					}
					// 获得字段类型名称
					String type = rs.getString("TYPE_NAME");
					// 获得字段大小
					int size = rs.getInt("COLUMN_SIZE");
					// 获得字段备注
					String remark = rs.getString("REMARKS");
					// System.out.println(columnName + "," + type + "," + size + "," + remark);
					TableEntity te = new TableEntity();
					te.setColumnName(columnName);
					te.setType(type);
					te.setSize(size);
					te.setRemark(remark);
					list.add(te);
				}
				// 生成代码
				rs.close();
				// 生成实体
				String entityClass = GenerateCodeUtil.generateEntityClass(list, tableName, packageName);
				// 生成dao
				String entityDaoClass = GenerateCodeUtil.generateEntityDaoClass(tableName, packageName);
				// 生成接口
				String interfaceClass = GenerateCodeUtil.generateInterfaceClass(tableName, packageName);
				// 生成实现
				String interfaceImplClass = GenerateCodeUtil.generateInterfaceImplClass(tableName, packageName);
				// 生成控制类
				String controller = GenerateCodeUtil.generateController(tableName, packageName);
				// System.out.println("实体\n" + entityClass);
				// System.out.println("dao\n" + entityDaoClass);
				// System.out.println("接口\n" + interfaceClass);
				// System.out.println("实现\n" + interfaceImplClass);
				// System.out.println("控制类\n" + controller);

				// 写入文件
				GenerateFileUtil.writeToFile(entityClass);
				GenerateFileUtil.writeToFile(entityDaoClass);
				GenerateFileUtil.writeToFile(interfaceClass);
				GenerateFileUtil.writeToFile(interfaceImplClass);
				GenerateFileUtil.writeToFile(controller);

				System.out.println((++count) + " : > " + tableName + " 代码生成成功....");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将表字段转为属性字段<br/>
	 * 
	 * @param columnName
	 * @return
	 */
	public static String transToFiled(String columnName) {
		StringBuffer sb = new StringBuffer("");
		char[] array = columnName.toCharArray();
		Boolean flag = false;
		for (char c : array) {
			if (c == '_') {
				flag = true;
				continue;
			}
			if (flag) {
				sb.append(Character.toUpperCase(c));
				flag = false;
			} else {
				sb.append(Character.toLowerCase(c));
			}
		}
		return sb.toString();
	}

	/**
	 * 根据数据库表字段类型判断 解析 实体属性字段类型<br/>
	 * 
	 * @param type
	 * @return
	 */
	public static String getColumnType(String type) {
		String filedType = null;
		// 判断类型
		if (type.equalsIgnoreCase("smallint")) {
			filedType = "Integer";
		} else if (type.equalsIgnoreCase("VARCHAR")) {
			filedType = "String";
		} else if (type.equalsIgnoreCase("TEXT")) {
			filedType = "String";
		} else if (type.equalsIgnoreCase("DATETIME")) {
			filedType = "DateTime";
			importList.add("import java.util.Date");
		} else if (type.equalsIgnoreCase("CHAR")) {
			filedType = "String";
		} else {
			filedType = "Object";
		}
		return filedType;
	}

	/**
	 * 创建表对应的实体<br/>
	 * 
	 * @param list
	 */
	public static String generateEntityClass(List<TableEntity> list, String tableName, String packageName) {
		StringBuffer sb = new StringBuffer("");
		String entityName = transTableName(tableName);
		// 包
		sb.append("package ").append(packageName).append(".entity;").append("\n");
		sb.append("\n");
		// 导包
		sb.append("import javax.persistence.Entity;").append("\n");
		sb.append("import javax.persistence.Table;").append("\n");
		sb.append("import org.hibernate.annotations.Cache;").append("\n");
		sb.append("import org.hibernate.annotations.CacheConcurrencyStrategy;").append("\n");
		sb.append("import org.hibernate.annotations.DynamicInsert;").append("\n");
		sb.append("import org.hibernate.annotations.DynamicUpdate;").append("\n");
		sb.append("import ").append(importMap.get("IdEntity") + ";").append("\n");

		sb.append("\n");
		// 注解
		sb.append("@Entity").append("\n");
		sb.append("@Table(name = \"" + tableName + "\")").append("\n");
		sb.append("@DynamicInsert").append("\n");
		sb.append("@DynamicUpdate").append("\n");
		sb.append("@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)").append("\n");
		sb.append("public class " + entityName + " extends IdEntity<" + entityName + "> {\n");
		sb.append("\n");
		// 生成序列化id
		sb.append("\tprivate static final long serialVersionUID =" + System.currentTimeMillis() + "L;").append("\n");
		// 生成属性
		for (TableEntity te : list) {
			String filed = transToFiled(te.getColumnName());
			String type = getColumnType(te.getType());
			// 生成属性注释
			sb.append("\t//").append(te.getRemark()).append("\n");
			sb.append("\t").append("private ").append(type).append(" ").append(filed).append(";").append("\n");
		}
		sb.append("\n");
		// 生成get,set方法
		for (TableEntity te : list) {
			String filed = transToFiled(te.getColumnName());
			String type = getColumnType(te.getType());
			// 生成get方法
			sb.append(createGetMethod(filed, type));
			// get、与set方法之间加一个换行
			sb.append("\n");
			// 生成set方法
			sb.append(createSetMethod(filed, type));
		}
		sb.append("}");
		return sb.toString();
	}

	/**
	 * 生成dao<br/>
	 * 
	 * @param tableName
	 * @param packageName
	 */
	public static String generateEntityDaoClass(String tableName, String packageName) {
		StringBuffer sb = new StringBuffer("");
		String entityName = transTableName(tableName);
		// 包
		sb.append("package " + packageName + ".dao;").append("\n");
		sb.append("\n");
		// 导包
		sb.append("import org.springframework.stereotype.Repository;").append("\n");
		sb.append("import " + importMap.get("BaseDao") + ";").append("\n");
		// 导入实体
		sb.append("import " + packageName + ".entity." + entityName + ";").append("\n");

		sb.append("\n");
		sb.append("@Repository").append("\n");
		sb.append("public class " + entityName + "Dao").append(" extends BaseDao<" + entityName + "> {").append("\n");

		sb.append("\n");
		sb.append("}");

		return sb.toString();
	}

	/**
	 * 生成实体的接口<br/>
	 * 
	 * @param tableName
	 * @param packageName
	 */
	public static String generateInterfaceClass(String tableName, String packageName) {
		StringBuffer sb = new StringBuffer("");
		// 转为实体名称
		String entityName = transTableName(tableName);
		// 包
		sb.append("package " + packageName + ".service;").append("\n");
		sb.append("import com.xiaoka.camelv.entity.vo.ResponseData;").append("\n");
		// 导入实体
		sb.append("import " + packageName + ".entity." + entityName + ";").append("\n");
		sb.append("import com.thinkgem.jeesite.common.persistence.Page;").append("\n");

		sb.append("\n");
		sb.append("public interface " + transTableName(tableName) + "Service {").append("\n");
		// 生成接口方法
		sb.append("\t").append("public " + entityName + " get(String id);").append("\n");
		sb.append("\t").append("public ResponseData save(" + entityName + " " + transFirstToLower(entityName) + ");")
				.append("\n");
		sb.append("\t").append("public ResponseData update(" + entityName + " " + transFirstToLower(entityName) + ");")
				.append("\n");
		sb.append("\t").append("public ResponseData delete(String id);").append("\n");
		sb.append("\t").append("public Page<" + entityName + "> find(Page<" + entityName + "> page, " + entityName + " "
				+ transFirstToLower(entityName) + ");").append("\n");
		sb.append("\n");
		sb.append("}");

		return sb.toString();
	}

	/**
	 * 生成实体接口的实现<br/>
	 * 
	 * @param tableName
	 * @param packageName
	 */
	public static String generateInterfaceImplClass(String tableName, String packageName) {
		StringBuffer sb = new StringBuffer("");
		String entityName = transTableName(tableName);
		// 包
		sb.append("package " + packageName + ".service.impl;").append("\n");
		sb.append("\n");
		// 导包
		sb.append("import org.springframework.stereotype.Service;").append("\n");
		// 导入接口
		sb.append("import " + packageName + ".service." + entityName + "Service;").append("\n");
		sb.append("import org.springframework.beans.factory.annotation.Autowired;").append("\n");
		sb.append("import " + packageName + ".dao." + entityName + "Dao;").append("\n");

		sb.append("import com.xiaoka.camelv.entity.vo.ResponseData;").append("\n");
		// 导入实体
		sb.append("import " + packageName + ".entity." + entityName + ";").append("\n");
		sb.append("import com.thinkgem.jeesite.common.persistence.Page;").append("\n");
		sb.append("import org.hibernate.criterion.Restrictions;").append("\n");
		sb.append("import com.xiaoka.camelv.constant.Constant;").append("\n");
		sb.append("import org.hibernate.criterion.DetachedCriteria;").append("\n");

		// 创建实现
		sb.append("\n");
		sb.append("@Service").append("\n");
		sb.append("public class " + entityName + "ServiceImpl implements " + entityName + "Service {").append("\n");
		// 注入dao
		sb.append("\t").append("@Autowired").append("\n");
		sb.append("\t").append("private " + entityName + "Dao " + transFirstToLower(entityName) + "Dao;").append("\n");
		// dao变量
		String dao = transFirstToLower(entityName) + "Dao";
		// 实体变量
		String field = transFirstToLower(entityName);

		// 添加get方法的实现
		sb.append("\t").append("@Override").append("\n");
		sb.append("\t").append("public " + entityName + " get(String id) {").append("\n");
		sb.append("\t\t").append("try {").append("\n");
		sb.append("\t\t\t").append("return " + dao + ".get(id);").append("\n");
		sb.append("\t\t").append("} catch (Exception e) {").append("\n");
		sb.append("\t\t\t").append("e.printStackTrace();").append("\n");
		sb.append("\t\t").append("}").append("\n");
		sb.append("\t\t").append("return null;").append("\n");
		sb.append("\t").append("}").append("\n\n");

		// 添加save方法的实现
		sb.append("\t").append("@Override").append("\n");
		sb.append("\t").append("public ResponseData save(" + entityName + " " + field + ") {").append("\n");
		sb.append("\t\t").append("ResponseData rd = new ResponseData(Constant.ERROR);").append("\n");
		sb.append("\t\t").append("try {").append("\n");
		sb.append("\t\t\t").append("" + dao + ".save(" + field + ");").append("\n");
		sb.append("\t\t\t").append("rd.setType(Constant.SUCCESS);").append("\n");
		sb.append("\t\t").append("} catch (Exception e) {").append("\n");
		sb.append("\t\t\t").append("e.printStackTrace();").append("\n");
		sb.append("\t\t").append("}").append("\n");
		sb.append("\t\t").append("return rd;").append("\n");
		sb.append("\t").append("}").append("\n\n");

		// 添加update方法的实现
		sb.append("\t").append("@Override").append("\n");
		sb.append("\t").append("public ResponseData update(" + entityName + " " + field + ") {").append("\n");
		sb.append("\t\t").append("ResponseData rd = new ResponseData(Constant.ERROR);").append("\n");
		sb.append("\t\t").append("try {").append("\n");
		sb.append("\t\t\t").append("" + dao + ".save(" + field + ");").append("\n");
		sb.append("\t\t\t").append("rd.setType(Constant.SUCCESS);").append("\n");
		sb.append("\t\t").append("} catch (Exception e) {").append("\n");
		sb.append("\t\t\t").append("e.printStackTrace();").append("\n");
		sb.append("\t\t").append("}").append("\n");
		sb.append("\t\t").append("return rd;").append("\n");
		sb.append("\t").append("}").append("\n\n");

		// 添加delete方法的实现
		sb.append("\t").append("@Override").append("\n");
		sb.append("\t").append("public ResponseData delete(String id) {").append("\n");
		sb.append("\t\t").append("ResponseData rd = new ResponseData(Constant.ERROR);").append("\n");
		sb.append("\t\t").append("try {").append("\n");
		sb.append("\t\t\t").append("" + dao + ".deleteById(id);").append("\n");
		sb.append("\t\t\t").append("rd.setType(Constant.SUCCESS);").append("\n");
		sb.append("\t\t").append("} catch (Exception e) {").append("\n");
		sb.append("\t\t\t").append("e.printStackTrace();").append("\n");
		sb.append("\t\t").append("}").append("\n");
		sb.append("\t\t").append("return rd;").append("\n");
		sb.append("\t").append("}").append("\n\n");

		// 添加分页查询方法的实现
		sb.append("\t").append("@Override").append("\n");
		sb.append("\t").append("public Page<" + entityName + "> find(Page<" + entityName + "> page, " + entityName + " "
				+ field + ") {").append("\n");
		sb.append("\t\t").append("try {").append("\n");
		sb.append("\t\t\t").append("DetachedCriteria dc = " + dao + ".createDetachedCriteria();").append("\n");
		sb.append("\t\t\t").append(
				"dc.add(Restrictions.eq(" + entityName + ".FIELD_DEL_FLAG, " + entityName + ".DEL_FLAG_NORMAL));")
				.append("\n");
		sb.append("\t\t\t").append("return " + dao + ".find(page, dc);").append("\n");
		sb.append("\t\t").append("} catch (Exception e) {").append("\n");
		sb.append("\t\t\t").append("e.printStackTrace();").append("\n");
		sb.append("\t\t").append("}").append("\n");
		sb.append("\t\t").append("return null;").append("\n");
		sb.append("\t").append("}").append("\n\n");

		sb.append("\n");
		sb.append("}");

		return sb.toString();
	}

	/**
	 * 生成控制类<br/>
	 * 
	 * @param tableName
	 * @param packageName
	 * @return
	 */
	public static String generateController(String tableName, String packageName) {
		StringBuffer sb = new StringBuffer("");
		String entityName = transTableName(tableName);
		// 包
		sb.append("package " + packageName + ".web;").append("\n");
		sb.append("\n");
		// 导包
		sb.append("import org.slf4j.Logger;").append("\n");
		sb.append("import org.slf4j.LoggerFactory;").append("\n");
		sb.append("import org.springframework.stereotype.Controller;").append("\n");
		sb.append("import org.springframework.web.bind.annotation.RequestMapping;").append("\n");
		sb.append("import " + importMap.get("BaseController") + ";").append("\n");
		sb.append("import " + packageName + ".service." + entityName + "Service;").append("\n");
		sb.append("").append("\n");
		// 注解
		sb.append("@Controller").append("\n");
		sb.append("@RequestMapping(value = \"${adminPath}/\")").append("\n");
		sb.append("public class " + entityName + "Controller extends BaseController {").append("\n\n");
		// log4j
		sb.append("\tprivate Logger logger = LoggerFactory.getLogger(getClass());").append("\n\n");
		// 注入service
		sb.append("\t").append("@Autowired").append("\n");
		sb.append("\t").append("private " + entityName + "Service " + transFirstToLower(entityName) + "Service;")
				.append("\n\n");

		// 添加请求方法

		sb.append("").append("\n");
		sb.append("}").append("\n");

		return sb.toString();
	}

	/**
	 * 获取get方法<br/>
	 * 
	 * @param filed
	 * @param type
	 * @return
	 */
	public static String createGetMethod(String filed, String type) {
		StringBuffer sb = new StringBuffer("");
		sb.append("\t").append("public " + type + " get" + transToUpperCase4Method(filed) + "(){").append("\n");
		sb.append("\t\t").append("return " + filed).append(";").append("\n");
		sb.append("\t").append("}").append("\n");
		return sb.toString();
	}

	/**
	 * 获取set方法<br/>
	 * 
	 * @param filed
	 * @param type
	 * @return
	 */
	public static String createSetMethod(String filed, String type) {
		StringBuffer sb = new StringBuffer("");
		sb.append("\t").append("public void  set" + transToUpperCase4Method(filed))
				.append("(" + type + " " + filed + "){\n");

		sb.append("\t\t").append("this." + filed + "=" + filed).append(";\n");
		sb.append("\t").append("}").append("\n");
		return sb.toString();
	}

	/**
	 * 将属性转为第一个字母大写<br/>
	 * 
	 * @param filed
	 * @return
	 */
	public static String transToUpperCase4Method(String filed) {
		return Character.toUpperCase(filed.charAt(0)) + filed.substring(1);
	}

	/**
	 * 将表明转为实体名称<br/>
	 * 
	 * @param tableName
	 * @return
	 */
	public static String transTableName(String tableName) {
		// 去除表前缀
		if (!StringUtils.isBlank(TABLE_PREFFIX)) {
			tableName = tableName.substring(TABLE_PREFFIX.length());
		}
		StringBuffer sb = new StringBuffer("");
		char[] array = tableName.toCharArray();
		boolean first = true;
		for (char c : array) {
			if (first) {
				sb.append(Character.toUpperCase(c));
				first = false;
				continue;
			}
			// 表之间的连接符
			if (c == '_') {
				first = true;
				continue;
			}
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 首字母小写<br/>
	 * 
	 * @param filed
	 * @return
	 */
	public static String transFirstToLower(String filed) {

		return filed.substring(0, 1).toLowerCase() + filed.substring(1);
	}

	public static void main(String[] args) {
		System.out.println(transTableName("county"));
	}
}
